// JavaScript Document

function BlockView(farmView, parentNode, x, y)
{
    if (this instanceof BlockView)
    {
        // TODO. all common used animation, images blah blah const should be moved to CommonResource like files. and use function to got them but not use in defines.
        // same as the magic numbers. should use some tools or got from commonResource. define a good struct to combine them.
        this.farmView = farmView;
        this.listenObject = null;
        this.helperNode = new SceneNode(parentNode);
        this.backImg = new ImageObject(g_imgMgr.getImage(IMAGE_FARM_BLOCK_COMMON), new Point(0, 0), true);
        this.backImg.setAabb(new Rect(0, 0, 200, 150));
        this.backNode = new SceneNode(this.helperNode, this.backImg);
        this.highlightNode = new SceneNode(this.helperNode, g_imgMgr.getImage(IMAGE_FARM_BLOCK_HIGHLIGHT));
        this.highlightNode.enableHitTest(false);
        this.highlightNode.enable(false);
        this.x = x;
        this.y = y;
        this.data = null;
        this.helperNode.setPosition(new Point(x, y));
        this.backNode.setLocalAabb(new Rect(0, 0, 200, 150));
        this.highlightNode.setLocalAabb(new Rect(0, 0, 200, 150));
        
        this.backNode.eventMouseOver = bind(this.onMouseOver, this);
        this.backNode.eventMouseLeave = bind(this.onMouseLeave, this);
        this.backNode.eventMouseClick = bind(this.onMouseClick, this);
        
        // here create block renderer layers.
        // plants
        this.plantImg = new ImageObject(null, null, false);
        this.plantNode = new SceneNode(this.helperNode, this.plantImg);
        this.plantNode.setPosition(new Point(80, 40));
        this.plantNode.enableHitTest(false);
        this.plantNode.enable(false);
        // weeds
        this.weedNodes = [];

        // worms
        this.wormNodes = [];

        
        this.tipWindow = null;
        this.farmState = null;
        // others, like worm.
    }
    else
    {
        return new BlockView(farmView, parentNode, x, y);
    }
}

BlockView.prototype.highlight = function(highlight)
{
    this.highlightNode.enable(highlight);
	if (highlight && this.data)
	{
		if (this.tipWindow)
		{
			this.tipWindow.setActive(true);
            this.tipWindow.setText(this.data.getTipText());
		}
	}
	else
	{
		if (this.tipWindow)
		{
			this.tipWindow.setActive(false);
		}
	}
}

BlockView.prototype.onMouseOver = function()
{
    this.highlight(true);
}

BlockView.prototype.onMouseLeave = function()
{
    this.highlight(false);
}

BlockView.prototype.onMouseClick = function()
{
	if (this.farmState)
	{
		this.farmState.clickFarmBlock(this.listenObject);
	}
}

BlockView.prototype.getListenerObject = function()
{
	return this.listenObject;
}

BlockView.prototype.updateFromData = function(blockData)
{
    // update by blockData from network. 
    this.data = blockData;
    if (blockData.landDry)
    {
		this.backImg.updateImg(g_imgMgr.getImage(IMAGE_FARM_BLOCK_DRY));
    }
    else
    {
		this.backImg.updateImg(g_imgMgr.getImage(IMAGE_FARM_BLOCK_COMMON));
    }
	// plant
	
	if (this.data.status == Models.FarmBlock.PLANT)
	{
		this.plantNode.enable(true);
	}
	else
	{
		this.plantNode.enable(false);
	}
    var veg = blockData.veg;
    var curStage = blockData.getStage();
    if (curStage == Models.FarmStage.GROWUP)
    {
        var growupStage = blockData.getGrowupStage();
        this.plantImg.updateImg(g_imgMgr.getImage(veg.getStageImgData(growupStage).img));
		this.plantImg.setOffset(veg.getStageImgData(growupStage).offset);
    }
	else if (curStage == Models.FarmStage.FLOWER)
	{
		this.plantImg.updateImg(g_imgMgr.getImage(veg.getFlowerImgData().img));
		this.plantImg.setOffset(veg.getFlowerImgData().offset);
	}
	else if (curStage == Models.FarmStage.AFTER_HARVEST)
	{
		this.plantImg.updateImg(g_imgMgr.getImage(veg.getHarvestImgData().img));
		this.plantImg.setOffset(veg.getHarvestImgData().offset);
	}

    for (var i = 0; i < this.weedNodes.length; i++)
    {
        this.weedNodes[i].enable(false);
    }
    
    for (var i = 0;  i < blockData.weeds; i++)
    {
        if (i >= this.weedNodes.length)
        {
            var weedImg = new ImageObject(g_imgMgr.getImage(ICON_PLACE_WEEDS), new Point(50 + i * 15, 20 + i * 12), false);
            var node = new SceneNode(this.helperNode, weedImg);
            node.enableHitTest(false);
            this.weedNodes.push(node);
        }
        this.weedNodes[i].enable(true);
    }   
    
    for (var i = 0; i < this.wormNodes.length; i++)
    {
        this.wormNodes[i].enable(false);
    }
    
    for (var i = 0;  i < blockData.pests; i++)
    {
        if (i >= this.wormNodes.length)
        {
            var wormImg = new ImageObject(g_imgMgr.getImage(ICON_PLACE_WORMS), new Point(80 + i * 10, 20 + i * 10), false);
            var node = new SceneNode(this.helperNode, wormImg);
            node.enableHitTest(false);
            this.wormNodes.push(node);
        }
        this.wormNodes[i].enable(true);
    }
}

BlockView.prototype.onExpNotified = function(e)
{
	this.farmView.onExpNotified(e.str, this.helperNode);
}

function FarmView(parentNode, tipWindow, farmState, farm)
{
    if (this instanceof FarmView)
    {
        this.expTipManager = new FloatingTipManager(1, new Point(0, -30));
        this.farmState = farmState;
        this.tipWindow = tipWindow;
        this.blocks = new Array();
        // construct block by 
        var startX = 240;
        var startY = 20;
        var x_intervalX = 113;
        var x_intervalY = 54;
        var y_intervalX = -113;
        var y_intervalY = 54;
        this.farmNode = new SceneNode(parentNode);
        for (var i = 0; i < Models.Farm.TOTAL; i++)
        {
            var row = Math.floor(i / Models.Farm.COL);
            var col = i % Models.Farm.COL;
            this.blocks[i] = new BlockView(this, this.farmNode, startX + row * y_intervalX + col * x_intervalX, 
                    startY + row * y_intervalY + col * x_intervalY);
            
            this.blocks[i].tipWindow = tipWindow;
            this.blocks[i].farmState = farmState;
        }
        
        for (var i = 0; i < Models.Farm.TOTAL; i++)
        {
            farm.blocks[i].registerListener(Models.Event.FarmBlock.UPDATE, bind(this.blocks[i].updateFromData, this.blocks[i]));
            this.blocks[i].listenObject = farm.blocks[i];
            farm.blocks[i].updateListeners(Models.Event.FarmBlock.UPDATE, farm.blocks[i]);
            farm.blocks[i].registerListener(Models.Event.FarmBlock.EXP_UPDATE, bind(this.blocks[i].onExpNotified, this.blocks[i]));
        }
    }
    else
    {
        return new FarmView(parentNode, tipWindow, farmState, farm);
    }
}

FarmView.prototype.onExpNotified = function(exp_text, node)
{
	if (node)
	{
		this.expTipManager.startTip(new Point(100, 50), exp_text, node);
	}
	else
	{
		this.expTipManager.startTip(getApp().getCursorPos(), exp_text);
	}
}

FarmView.prototype.setPosition = function(pos)
{
	this.farmNode.setPosition(pos);
}

FarmView.prototype.update = function(interval)
{
	this.expTipManager.update(interval);
}

FarmView.prototype.draw = function(ctx)
{
	this.expTipManager.draw(ctx);
}

function Background(parentNode)
{
    if (this instanceof Background)
    {
        this.node = new SceneNode(parentNode, g_imgMgr.getImage(IMAGE_BACK_GROUND));
    }
    else
    {
        return new Background(parentNode);
    }
}

Background.prototype.update = function(interval)
{
	
}